package com.zenithmind.common.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 安全工具类，提供获取当前用户信息的方法
 * 替代旧的CurrentUserHolder，直接从Spring Security上下文获取用户信息
 */
@Slf4j
@Component
public class SecurityUtils {

    private static final String CLAIMS_SUB = "sub";
    private static final String CLAIMS_USER_ID = "user_id";
    private static final String CLAIMS_EMAIL = "email";
    private static final String CLAIMS_PREFERRED_USERNAME = "preferred_username";

    /**
     * 获取当前认证用户ID
     * @return 用户ID，未认证返回null
     */
    public static String getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return null;
        }

        if (authentication instanceof JwtAuthenticationToken) {
            JwtAuthenticationToken jwtToken = (JwtAuthenticationToken) authentication;
            Map<String, Object> claims = jwtToken.getToken().getClaims();
            
            // 优先从自定义声明中获取用户ID
            if (claims.containsKey(CLAIMS_USER_ID)) {
                return (String) claims.get(CLAIMS_USER_ID);
            }
            
            // 其次从标准sub声明获取
            if (claims.containsKey(CLAIMS_SUB)) {
                return (String) claims.get(CLAIMS_SUB);
            }
        }
        
        // 如果是其他类型的认证，尝试获取Principal
        return authentication.getName();
    }

    /**
     * 获取当前认证用户的所有角色
     * @return 角色列表
     */
    public static Collection<String> getCurrentUserRoles() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            return Collections.emptyList();
        }

        return authentication.getAuthorities().stream()
            .map(GrantedAuthority::getAuthority)
            .collect(Collectors.toList());
    }

    /**
     * 判断当前用户是否拥有指定角色
     * @param role 角色名称
     * @return 是否拥有该角色
     */
    public static boolean hasRole(String role) {
        String roleWithPrefix = role.startsWith("ROLE_") ? role : "ROLE_" + role;
        return getCurrentUserRoles().stream()
            .anyMatch(r -> r.equals(roleWithPrefix));
    }

    /**
     * 获取当前认证用户的邮箱
     * @return 邮箱地址，未包含则返回null
     */
    public static String getCurrentUserEmail() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof JwtAuthenticationToken) {
            JwtAuthenticationToken jwtToken = (JwtAuthenticationToken) authentication;
            Map<String, Object> claims = jwtToken.getToken().getClaims();
            
            if (claims.containsKey(CLAIMS_EMAIL)) {
                return (String) claims.get(CLAIMS_EMAIL);
            }
        }
        return null;
    }

    /**
     * 获取当前用户名
     * @return 用户名
     */
    public static String getCurrentUsername() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof JwtAuthenticationToken) {
            JwtAuthenticationToken jwtToken = (JwtAuthenticationToken) authentication;
            Map<String, Object> claims = jwtToken.getToken().getClaims();
            
            if (claims.containsKey(CLAIMS_PREFERRED_USERNAME)) {
                return (String) claims.get(CLAIMS_PREFERRED_USERNAME);
            }
        }
        
        return authentication != null ? authentication.getName() : null;
    }
} 